﻿#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEngine;
/// <summary>
/// CMD管理器
/// </summary>
public partial class ESF_Utility
{
    #region ExcuteFile 执行文件
    /// <summary>
    /// 执行文件
    /// </summary>
    /// <param name="_fileName">文件名称</param>
    /// <returns>错误信息</returns>
    public static Exception ExcuteFile(string _fileName)
    {
        return ExcuteFile(_fileName, string.Empty);
    }

    /// <summary>
    /// 执行文件
    /// </summary>
    /// <param name="_fileName">文件名称</param>
    /// <param name="_arguments">参数</param>
    /// <returns>错误信息</returns>
    public static Exception ExcuteFile(string _fileName, string _arguments)
    {
        Exception error = default(Exception);
        try
        {
            using (Process process = new Process())
            {
                ProcessStartInfo psi = new ProcessStartInfo(_fileName, _arguments);
                process.StartInfo = psi;
                process.Start();
                process.WaitForExit();
            }
        }
        catch (Exception ep)
        {
            error = ep;
            ESF_P.ESF_Error(ep.Message);
        }
        return error;
    }
    #endregion

    #region ExcuteAsBat 以Bat模式执行文本
    /// <summary>
    /// 以Bat模式执行文本
    /// </summary>
    /// <param name="_batText">bat文本</param>
    /// <returns>错误信息</returns>
    public static Exception ExcuteAsBat(string _batText)
    {
        string path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".bat");
        File.WriteAllText(path, _batText, Encoding.UTF8);
        Exception rst = ExcuteFile(path, string.Empty);
        File.Delete(path);
        return rst;
    }

    /// <summary>
    /// 执行Cmd命令
    /// </summary>
    /// <param name="_commands">命令行</param>
    /// <returns>错误信息</returns>
    public static Exception ExcuteCmd(params string[] _commands)
    {
        string path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".bat");
        File.WriteAllLines(path, _commands);
        Exception ep = ExcuteFile(path);
        File.Delete(path);
        return ep;
    }
    #endregion

    #region OpenUrl 打开Url页面
    /// <summary>
    /// 打开Url页面
    /// </summary>
    /// <param name="_url">Url地址</param>
    public static void OpenUrl(string _url)
    {
        OpenFile(_url);
    }
    #endregion

    #region OpenFile 打开文件
    /// <summary>
    /// 打开文件
    /// </summary>
    /// <param name="_filePath">文件路径</param>
    public static void OpenFile(string _filePath)
    {
        Process.Start(_filePath);
    }
    #endregion

    #region OpenFile 打开文件
    /// <summary>
    /// 打开文件
    /// </summary>
    /// <param name="_object">对象</param>
    public static void OpenFile(UnityEngine.Object _object)
    {
        OpenFile(Path.GetFullPath(AssetDatabase.GetAssetPath(_object)));
    }
    #endregion

    #region SaveLogFile 保存日志文件
    /// <summary>
    /// 保存日志
    /// </summary>
    /// <param name="_fileNameWithoutExtension">文件名称</param>
    /// <param name="_relativeSaveLogDirectory">相对于日志根目录路径</param>
    /// <param name="_content">文件内容</param>
    /// <returns>保存文件地址</returns>
    public static string SaveLogFile(string _fileNameWithoutExtension,string _relativeSaveLogDirectory, string _content)
    {
        string folder = Path.Combine(globalSaveLogFolder, _relativeSaveLogDirectory);
        if (!Directory.Exists(folder))
        {
            Directory.CreateDirectory(folder);
        }
        string path = GetPath(_fileNameWithoutExtension, folder, enESF_UnityFileExt.TextAsset);
        ESF_P.ESF_Log($"Save log to=>{path}");
        File.WriteAllText(path, _content);
        return path;
    }
    #endregion

    #region ClearLogFolder 清空日志目录
    /// <summary>
    /// 清空日志目录
    /// </summary>
    /// <param name="_relativeSaveLogDirectory">相对于日志根目录路径</param>
    public static void ClearLogFolder(string _relativeSaveLogDirectory)
    {
        string folder = Path.Combine(globalSaveLogFolder, _relativeSaveLogDirectory);
        DeleteFolder(folder);
    }
    #endregion

    #region DeleteFolder 删除文件夹
    /// <summary>
    /// 删除文件夹
    /// </summary>
    /// <param name="_folder">文件夹</param>
    public static void DeleteFolder(string _folder)
    {
        if (Directory.Exists(_folder))
        {
            ExcuteCmd(string.Format("rd /s /q \"{0}\" & ping 127.0.0.1 -n 5>nul &exit", _folder));
        }
        else
        {
            ESF_P.ESF_LogFormat("CMD can not found folder=>{0}", _folder);
        }
    }
    #endregion

    #region CreateFolder 创建文件夹
    /// <summary>
    /// 创建文件夹
    /// </summary>
    /// <param name="_folder">文件夹</param>
    public static void CreateFolder(string _folder)
    {
        if (!Directory.Exists(_folder))
        {
            Directory.CreateDirectory(_folder);
        }
    }
    #endregion

    #region ClearFolder 清空文件夹
    /// <summary>
    /// 清空文件夹
    /// </summary>
    /// <param name="_folder">文件夹</param>
    public static void ClearFolder(string _folder)
    {
        DeleteFolder(_folder);
        CreateFolder(_folder);
    }
    #endregion

    #region CopyToX 从源文件夹复制到目标文件夹
    /// <summary>
    /// 从源文件夹复制到目标文件夹
    /// </summary>
    /// <param name="_srcFolder">源文件夹</param>
    /// <param name="_targetFolder">目标文件夹</param>
    /// <param name="_title">标题</param>
    /// <param name="_funcProcessCSharp">CSharp内容处理</param>
    public static void CopyCSharpToX(string _srcFolder, 
        string _targetFolder, 
        string _title, 
        Func<string, string> _funcCSharp,
        Func<string, string> _funcPath)
    {
        string directory = Path.Combine(_targetFolder, Path.GetFileName(_srcFolder));
        ESF_Utility.DeleteFolder(directory);
        if (!Directory.Exists(directory))
        {
            Directory.CreateDirectory(directory);
        }
        List<ESF_CollectAsset_CSharp> nodes = ESF_Utility.CollectFile<ESF_CollectAsset_CSharp>(
        new string[] { _srcFolder }, enESF_AssetFilterClassify.Script, enESF_DisplayProgressBarClassify.Normal);
        if (nodes != null)
        {
            string subPath = string.Empty;
            string code = string.Empty;
            ESF_BuildTextAsset bta = new ESF_BuildTextAsset("", "", enESF_UnityFileExt.CS, "");
            float progress = 0;
            int count = nodes.Count;
            foreach (var n in nodes)
            {
                code = _funcCSharp(File.ReadAllText(n.path));
                subPath = _funcPath(GetSubTo(n.path, _srcFolder));
                subPath = Path.Combine(_targetFolder, subPath).ESF_TransPathSeparatorCharToUnityChar();
                bta.SetDirectory(Path.GetDirectoryName(subPath));
                bta.SetFileName(Path.GetFileNameWithoutExtension(subPath));
                bta.SetText(code);
                bta.CreateAsset();
                progress++;
                EditorUtility.DisplayProgressBar($"{_title}", bta.filePath, progress / count);
            }
        }
    }
    #endregion

    #region WaitTime 等待指定时间
    /// <summary>
    /// 等待指定时间
    /// </summary>
    /// <param name="_waitTime">等待时间</param>
    public static void WaitTime(int _waitTime = 4)
    {
        ExcuteCmd($"ping 127.0.0.1 -n {_waitTime}>nul &exit");
    }
    #endregion

    #region CombineSFCommandLineArgs 合成SF命令行参数
    /// <summary>
    /// 合成SF命令行参数
    /// </summary>
    const string mCmdArgName = "-SFArgs=";
    /// <summary>
    /// 追加StrayFog命令行参数
    /// </summary>
    /// <param name="_arguments">参数</param>
    /// <returns>命令行参数</returns>
    public static string CombineSFCommandLineArgs(params string[] _arguments)
    {
        string args = string.Empty;
        if (_arguments != null && _arguments.Length > 0)
        {
            args = " " + mCmdArgName + _arguments.ESF_JsonSerialize();
        }
        return args;
    }
    #endregion

    #region GetSFCommandLineArgs 获得SF命令行参数
    /// <summary>
    /// 获得SF命令行参数
    /// </summary>
    /// <returns>参数</returns>
    public static string[] GetSFCommandLineArgs()
    {
        string[] args = new string[0];
        string[] clas = Environment.GetCommandLineArgs();
        if (clas != null && clas.Length > 0)
        {
            foreach (string s in clas)
            {
                if (s.Trim().StartsWith(mCmdArgName))
                {
                    args = s.Remove(0, mCmdArgName.Length).ESF_JsonDeserialize<string[]>();
                    break;
                }
            }
        }
        return args;
    }
    #endregion

    #region Restart 自动重启
    /// <summary>
    /// 重启菜单
    /// </summary>
    const string mcCmd_ExecuteApplicationRestartMenu = "Cmd_ExecuteApplicationRestartMenu.txt";
    /// <summary>
    /// 自动重启
    /// </summary>
    public static void RestartEditor()
    {
        string bat = TraceCaller_RelativeFrom();
        bat = bat.ESF_CombinePath(mcCmd_ExecuteApplicationRestartMenu).ESF_TransPathSeparatorCharToUnityChar();
        bat = File.ReadAllText(bat);
        Process p = Process.GetCurrentProcess();
        string path = Path.Combine(EditorApplication.applicationPath, p.MainModule.FileName);
        MethodBase method = MethodBase.GetCurrentMethod(); //typeof(EditorStrayFogExecute).GetMethod("ExecuteBuildPackage");
        string batCode = bat.CompilerCSharp(
            new
            {
                Pid = p.Id,
                EngineExe = path,
                ProjectPath = globalAssetsFolderPath,
                LogFile = Path.Combine(SFGlobalSetting.persistentDataPath, "Restart.log"),
                ExecuteMethod = method.DeclaringType.FullName + "." + method.Name
            });
        ESF_P.ESF_Log($"Bat Code=>{batCode}");
        ExcuteCmd(batCode);
    }
    #endregion
}
#endif
